﻿using Newtonsoft.Json.Linq;
using System;
using System.IO;
using up6.db.database;
using up6.db.model;
using up6.db.sql;
using up6.db.utils;
using up6.sql;
using up6.utils;

namespace up6.api.filemgr
{
    /// <summary>
    /// 更新记录：
    ///     2022-12-16 新增重命名文件逻辑
    /// </summary>
    public partial class rename : WebBase
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            var o = this.reqJson();
            var f = o.ToObject<FileInf>();

            //当前目录是根目录?
            bool isRootDir = PathTool.parentDir(f.pathRel) == "/";

            if (!f.fdTask)
            {
                this.renameFile(f);
            }
            //是子目录
            else if (!isRootDir)
            {
                this.renameChildDir(f);
            }
            //是根目录
            else
            {
                this.renameRootDir(f);
            }
        }

        void renameFile(FileInf f)
        {
            //新的相对路径
            f.pathRel = Path.Combine(PathTool.parentDir(f.pathRel), f.nameLoc);
            f.pathRel = f.pathRel.Replace('\\', '/');

            //根据相对路径(新)=>查找同名文件
            var s = new FileInf();
            s = SqlTable.build("up6_files").readOne<FileInf>(
                //相对路径=>/dir
                SqlWhere.build()
                .eq("f_pathRel", f.pathRel)
                .eq("f_deleted", false)
                );

            bool exist = s != null;

            //不存在同名文件
            if (!exist)
            {
                SqlTable.build("up6_files").update(
                    SqlSeter.build()
                    .set("f_nameLoc", f.nameLoc)
                    .set("f_nameSvr", f.nameLoc)
                    .set("f_pathRel", f.pathRel),
                    SqlWhere.build().eq("f_id", f.id)
                    );

                var ret = new JObject { { "state", true },
                    { "pathRel",f.pathRel} };
                this.toContent(ret);
            }
            //存在同名项
            else
            {
                var res = new JObject { { "state", false }, { "msg", "存在同名项" } };
                this.toContent(res);
            }
        }

        void renameChildDir(FileInf dir)
        {
            var pathRelOld = dir.pathRel;
            //root/dir/name => root/dir
            var index = dir.pathRel.LastIndexOf("/");
            dir.pathRel = dir.pathRel.Substring(0, index + 1);
            //root/dir/old => root/dir/new
            dir.pathRel += dir.nameLoc;
            var pathRelNew = dir.pathRel;

            var fd = SqlTable.build("up6_folders").readOne<FileInf>("f_id,f_pathRel",
                SqlWhere.build()
                .eq("f_pathRel", pathRelNew)
                .eq("f_deleted", false)
                );
            bool exist = fd != null;

            //不存在同名目录
            if (!exist)
            {   
                //更新相对路径
                SqlTable.build("up6_folders").update(
                    SqlSeter.build()
                    .set("f_nameLoc",dir.nameLoc)
                    .set("f_pathRel", pathRelNew),
                    SqlWhere.build().eq("f_id", dir.id)
                    );

                //更新子级文件和目录路径
                this.folder_renamed(pathRelOld, pathRelNew);
                var ret = new JObject { 
                    { "state", true },
                    { "pathRel",pathRelNew} 
                };
                this.toContent(ret);
            }
            //存在同名项
            else
            {
                var res = new JObject { { "state", false }, { "msg", "存在同名项" } };
                this.toContent(res);
            }
        }

        /// <summary>
        /// 重命名根级目录名称
        /// 更新记录：
        ///     2022-12-11 优化查询逻辑，使用相对路径查询
        /// </summary>
        void renameRootDir(FileInf dir)
        {
            //根据相对路径(新)=>查找同名文件夹
            var pathRel = "/" + dir.nameLoc;
            var s = SqlTable.build("up6_files").readOne<FileInf>(
                //相对路径=>/dir
                SqlWhere.build()
                .eq("f_pathRel", pathRel)
                .eq("f_deleted",false)
                );

            bool exist = s != null;

            //不存在同名目录
            if (!exist)
            {
                //查找目录旧的相对路径
                s = SqlTable.build("up6_files").readOne<FileInf>(
                    "f_pathRel",
                    SqlWhere.build().eq("f_id",dir.id));
                
                SqlTable.build("up6_files").update(
                    SqlSeter.build()
                    .set("f_nameLoc",dir.nameLoc)
                    .set("f_nameSvr",dir.nameLoc)
                    .set("f_pathRel", pathRel),
                    SqlWhere.build().eq("f_id",dir.id)
                    );

                //更新子级文件和目录路径
                this.folder_renamed(s.pathRel, pathRel);

                var ret = new JObject { { "state", true },
                    { "pathRel",pathRel} };
                this.toContent(ret);
            }
            //存在同名项
            else
            {
                var res = new JObject { { "state", false }, { "msg", "存在同名项" } };
                this.toContent(res);
            }
        }

        /// <summary>
        /// 目录名称更新，
        /// 1.更新数据表中所有子级文件相对路径
        /// 2.更新数据表中所有子级目录相对路径
        /// </summary>
        /// <param name=""></param>
        void folder_renamed(string pathRelOld, string pathRelNew)
        {
            DBConfig cfg = new DBConfig();
            SqlExec se = cfg.se();
            string sql = string.Format("update up6_files set f_pathRel=REPLACE(f_pathRel,'{0}/','{1}/') where CHARINDEX('{0}/',f_pathRel)=1",
                pathRelOld,
                pathRelNew
                );
            if (ConfigReader.dbType() == DataBaseType.Oracle)
            {
                sql = string.Format("update up6_files set f_pathRel=REPLACE(f_pathRel,'{0}/','{1}/') where instr(f_pathRel,'{0}/')=1",
                pathRelOld,
                pathRelNew
                );
            }
            se.exec(sql);

            //更新目录表
            sql = string.Format("update up6_folders set f_pathRel=REPLACE(f_pathRel,'{0}/','{1}/') where CHARINDEX('{0}/',f_pathRel)=1",
                pathRelOld,
                pathRelNew
                );
            if (ConfigReader.dbType() == DataBaseType.Oracle)
            {
                sql = string.Format("update up6_folders set f_pathRel=REPLACE(f_pathRel,'{0}/','{1}/') where instr(f_pathRel,'{0}/')=1",
                pathRelOld,
                pathRelNew
                );
            }
            se.exec(sql);
        }
    }
}